<template>
  <div style="position: relative">
    <p class="down">
      <Checkbox v-model="hasWater" v-if="isSetWater == 1">水印</Checkbox>
      <Checkbox
        :indeterminate="indeterminate"
        :model-value="checkAll"
        @click.prevent="handleCheckAll"
        >全选</Checkbox
      >
      <a
        href="javascript:;"
        v-if="checkAllGroup.length > 0"
        @click="downLoad(checkAllGroup)"
      >
        批量下载
      </a>
      <a
        href="javascript:;"
        v-else
        :disabled="true"
        @click="downLoad(checkAllGroup)"
      >
        批量下载
      </a>
    </p>

    <div class="inner">
      <CheckboxGroup v-model="checkAllGroup" @on-change="checkAllGroupChange">
        <template v-for="item in imgsArr_c">
          <div
            :key="item.thumb_url"
            v-if="item.thumb_url || item.file_url"
            class="img-box default-card-animation demo-upload-list"
            :style="{
              width: imgWidth + 'px',
              height: item._height + 40 + 'px',
              position: 'absolute',
            }"
            ref="imgBox"
          >
            <img
              :data-src="item.thumb_url"
              style="width: 100%"
              @click="clickbigimg(item)"
              @error="erroImg"
            />
            <div
              class="mask"
              :style="{
                height: item._heightMask + 'px',
                paddingTop: item._heightMask / 2 + 'px',
              }"
              v-if="item.type == 2"
            >
              <Icon type="md-play" :size="40" @click="clickbigimg(item)" />
            </div>
            <div class="action">
              <Checkbox :label="item.id">&nbsp;</Checkbox>
              <p>
                下载：<span>{{ item.download_num }}</span>
                <a
                  class="ivu-ml-8"
                  href="javascript:;"
                  @click="downLoad(item.id)"
                  >下载</a
                >
              </p>
            </div>
          </div>
        </template>
      </CheckboxGroup>
    </div>
    <Modal
      v-model="pigimgmodel"
      title="预览视频"
      :width="600"
      :draggable="true"
      footer-hide
    >
      <video
        :src="src"
        style="width: 100%; max-height: 600px"
        controls
        :disablePictureInPicture="true"
        controlslist="nodownload nofullscreen"
        ref="vedio"
      ></video>
    </Modal>
  </div>
</template>
<script>
import Setting from "@/setting";
import util from "@/libs/util";
import Base64 from "@/libs/base64";
import defaultImg from "@/assets/images/default.jpg";

export default {
  name: "waterfall",
  props: ["imgList", "viewHeight", "currentId", "isSetWater"],
  data() {
    return {
      imgBoxEls: "",
      imgsArr_c: [],
      loadedCount: 0,
      beginIndex: 0,
      colNum: 2,
      colWidth: 260,
      imgWidth: 260,
      colsHeightArr: [],
      pigimgmodel: false,
      src: "",
      bigType: "",
      top: 0,
      checkAllGroup: [],
      indeterminate: false,
      checkAll: false,
      fileUrl: "",
      defaultImg: defaultImg,
      hasWater: true,
    };
  },

  watch: {
    imgList(newVal, oldVal) {
      this.checkAllGroup = [];
      this.checkAll = false;
      this.indeterminate = false;
      this.loadedCount = 0;
      this.imgsArr = this.imgList;
      this.beginIndex = 0;
      this.preLoad();
      this.hasWater = this.isSetWater == 1 ? true : false;
    },
    pigimgmodel(e) {
      if (!e && this.bigType == 2) {
        this.$refs.vedio.pause();
      }
    },
  },
  methods: {
    checkAllGroupChange(data) {
      if (data.length === this.imgList.length) {
        this.indeterminate = false;
        this.checkAll = true;
      } else if (data.length > 0) {
        this.indeterminate = true;
        this.checkAll = false;
      } else {
        this.indeterminate = false;
        this.checkAll = false;
      }
    },
    handleCheckAll() {
      if (this.indeterminate) {
        this.checkAll = false;
      } else {
        this.checkAll = !this.checkAll;
      }
      this.indeterminate = false;

      if (this.checkAll) {
        let ids = [];
        this.imgList.forEach((item) => {
          ids.push(item.id);
        });
        this.checkAllGroup = ids;
      } else {
        this.checkAllGroup = [];
      }
    },
    downLoad(id) {
      let params = {
        id: this.currentId,
        file_ids: id,
        download_type: "other",
        is_water: this.hasWater ? 1 : 0,
      };
      let playload = Base64.b64EncodeUnicode(JSON.stringify(params));
      this.fileUrl =
        Setting.request.apiBaseURL +
        `/v1/buss/tool/download?auth_access_token=${util.cookies.get(
          "token"
        )}&playload=${playload}`;
      window.open(this.fileUrl);
      setTimeout(() => {
        this.$emit("refresh");
      }, 500);
    },
    clickbigimg(data) {
      if (data.file_url) {
        if (data.type == 2) {
          this.src = data.file_url;
          this.bigType = data.type;
          this.pigimgmodel = true;
        } else {
          let imgArr = [];
          this.imgsArr_c.forEach((item) => {
            if (item.type == 1) {
              imgArr.push(item.file_url);
            }
          });
          let index = imgArr.findIndex((item) => {
            return item == data.file_url;
          });
          this.$hevueImgPreview({
            multiple: true,
            nowImgIndex: index,
            imgList: imgArr,
          });
        }
      }
    },
    erroImg(e) {
      e.target.src = this.defaultImg;
    },
    preLoad() {
      // forEach 无法通过 item 直接修改数组元素，需用数组下标修改
      if (this.imgsArr.length == 0) {
        this.preloaded();
      }
      this.imgsArr.forEach((item, index) => {
        // if (index < this.loadedCount) return;
        // 无图则把高度设置为0
        if (!item.file_url && !item.thumb_url) {
          // 图片的高度
          this.imgsArr[index]._height = "0";
          ++this.loadedCount;
          // 当前图片都与处理完，则加载图片
          if (this.imgsArr.length === this.loadedCount) {
            this.preloaded();
          }
        } else {
          let img = new Image();
          img.src = item.thumb_url;
          img.onload = img.onerror = (e) => {
            // 若加载失败则设置图片高度与宽度一致，加载成功则动态计算图片高度

            this.imgsArr[index]._height =
              e.type === "load"
                ? Math.round(this.imgWidth * (img.height / img.width))
                : this.imgWidth;
            this.imgsArr[index]._heightMask =
              e.type === "load"
                ? Math.round((this.imgWidth - 10) * (img.height / img.width))
                : this.imgWidth - 10;
            if (e.type === "error") {
              this.imgsArr[index]._error = true;
            }
            ++this.loadedCount;
            // 当前图片都与处理完，则加载图片
            if (this.imgsArr.length === this.loadedCount) {
              this.preloaded();
            }
          };
        }
      });
    },
    preloaded() {
      // 开始渲染
      this.imgsArr_c = [].concat(this.imgsArr);
      this.$nextTick(() => {
        // 对每个元素进行排列
        this.waterfall();
      });
    },
    waterfall() {
      // 选择所有图片
      this.imgBoxEls = this.$refs["imgBox"];
      // 若没图片，则返回
      if (!this.imgBoxEls) return;
      let top, left, height;
      // 开始排列的坐标，若为0则重头排列，colsHeightArr 数组保存的是当前每一列的高度
      if (this.beginIndex === 0) this.colsHeightArr = [];
      for (let i = this.beginIndex; i < this.imgBoxEls.length; ++i) {
        if (!this.imgBoxEls[i]) return;
        // 当前图片的高度
        height = this.imgBoxEls[i].offsetHeight;
        // 第一行，则直接按顺序排列
        if (i < this.colNum) {
          this.colsHeightArr.push(height);
          top = 0;
          // colWidth 为列宽，等于图片宽度加 div 左右的padding，colWidth = imgWdith + 2 * padding
          left = i * this.colWidth;
        } else {
          // 找到当前最低的高度和其索引
          let minHeight = Math.min.apply(null, this.colsHeightArr);
          let minIdx = this.colsHeightArr.indexOf(minHeight);
          // 当前图片的 top，即当前图片应所在的高度
          top = minHeight;
          // 当前图片的 left，即当前图片应该排到目前高度最低那一列下面
          left = minIdx * this.colWidth;
          // 更新第 minIdx 列的高度
          this.colsHeightArr[minIdx] += height;
        }
        // 设置 img-box 位置
        this.imgBoxEls[i].style.top = top + "px";
        this.imgBoxEls[i].style.left = left + "px";
        // 当前图片在窗口内，则加载，这是用于后面的图片懒加载。viewHeight 为窗口高度
        let imgEl = this.imgBoxEls[i].children[0];
        imgEl.src = imgEl.getAttribute("data-src");
        imgEl.style.opacity = 1;
        if (i == this.imgBoxEls.length - 1) {
          this.top = top + height + "px";
        }
      }
      // 排列完之后，之后新增图片从这个索引开始预加载图片和排列，之前排列的图片无需在处理
      this.beginIndex = this.imgBoxEls.length;
    },
  },
};
</script>
<style scoped>
.inner {
  position: relative;
  /* overflow: auto; */
  height: 770px;
  overflow-y: auto;
  width: 100%;
}
.img-box {
  padding: 10px 10px 0 0;
  position: relative;
}
.img-box img {
  -webkit-transition: -webkit-transform 500ms ease-in-out;
  -moz-transition: -moz-transform 500ms ease-in-out;
  -o-transition: -o-transform 500ms ease-in-out;
  transition: transform 500ms ease-in-out;
}
.img-box img:hover {
  transform: translateY(-10px);
}
.img-box:hover .mask {
  display: block;
}
.demo-upload-list {
  position: relative;
}
.demo-upload-list-cover {
  color: #fff;
  font-size: 16px;
  cursor: pointer;
  margin: 0 2px;
}
.action {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 10px;
}
.down {
  position: absolute;
  top: -40px;
  right: 0px;
}
.mask {
  position: absolute;
  top: 10px;
  left: 0;
  right: 10px;
  background: rgba(7, 17, 27);
  text-align: center;
  color: #fff;
  box-sizing: border-box;
  opacity: 0.5;
}
.mask i {
  margin-top: -50%;
}
</style>
